<template>
  <div>
    <div class="container">
      <Toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        :mode="mode"
      />
      <Editor
        class="editor"
        v-model="valueHtml"
        :defaultConfig="editorConfig"
        :mode="mode"
        @onCreated="handleCreated"
        :style="{height: editorHeight}"
      />
    </div>
  </div>
</template>

<script lang="ts">
import '@wangeditor/editor/dist/css/style.css' // 引入 css

import { onBeforeUnmount, ref, shallowRef, onMounted, defineComponent, watch } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import type { IEditorConfig } from '@wangeditor/core';
import emitSocketProgress from '@uppy/utils/lib/emitSocketProgress';
// import { IEditorConfig } from '@wangeditor/editor'

export default defineComponent({
  components: { Editor, Toolbar },
  // emits: ['update:value'],
  props: {
    height: {
      type: [String, Number],
      default: 350
    },
    modelValue: String
  },
  computed: {
    editorHeight() {

      if (typeof this.height === 'string') {
        return this.height.match(/^\d+/)[0] + 'px'
      }

      return this.height + 'px'
      
    }
  },
  setup(props, {emit}) {
    
    // 编辑器实例，必须用 shallowRef
    const editorRef = shallowRef()
    // 初始化 MENU_CONF 属性
    const editorConfig: Partial<IEditorConfig> = {  // TS 语法
    // const editorConfig = {                       // JS 语法
        MENU_CONF: {}

        // 其他属性...
    }

    // 修改 uploadImage 菜单配置
    editorConfig.MENU_CONF['uploadImage'] = {
        server: '/api/file/upload',
        fieldName: 'file',
        maxFileSize: 2 * 1024 * 1024, // 1M
        // 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
        allowedFileTypes: ['image/*'],
        customInsert(res: any, insertFn: InsertFnType) {  // TS 语法
            // res 即服务端的返回结果
            const {data} = res
            const url = `/api/file/download/${data}`
            // 从 res 中找到 url alt href ，然后插入图片
            insertFn(url, data, url)
        },
        // 上传之前触发
        onBeforeUpload(file: File) { // TS 语法
        // onBeforeUpload(file) {    // JS 语法
            // file 选中的文件，格式如 { key: file }
            return file

            // 可以 return
            // 1. return file 或者 new 一个 file ，接下来将上传
            // 2. return false ，不上传这个 file
        },

        // 上传进度的回调函数
        onProgress(progress: number) {  // TS 语法
        // onProgress(progress) {       // JS 语法
            // progress 是 0-100 的数字
            console.log('progress', progress)
        },

        // 单个文件上传成功之后
        onSuccess(file: File, res: any) {  // TS 语法
        // onSuccess(file, res) {          // JS 语法
            console.log(`${file.name} 上传成功`, res)
        },

        // 单个文件上传失败
        onFailed(file: File, res: any) {   // TS 语法
        // onFailed(file, res) {           // JS 语法
            console.log(`${file.name} 上传失败`, res)
        },

        // 上传错误，或者触发 timeout 超时
        onError(file: File, err: any, res: any) {  // TS 语法
        // onError(file, err, res) {               // JS 语法
            console.log(`${file.name} 上传出错`, err, res)
        },
    }

    // 内容 HTML
    const valueHtml = ref('')

    watch(
      () => valueHtml.value,
      (val) => {
        console.log('update:modelValue');
        
        emit('update:modelValue', val)
      }
    )

    // 模拟 ajax 异步获取内容
    onMounted(() => {
        // setTimeout(() => {
        //     valueHtml.value = '<p>模拟 Ajax 异步设置内容</p>'
        // }, 1500)
    })

    const toolbarConfig = {}
    // const editorConfig = { placeholder: '请输入内容...' }

    // 组件销毁时，也及时销毁编辑器
    onBeforeUnmount(() => {
        const editor = editorRef.value
        if (editor == null) return
        editor.destroy()
    })

    const handleCreated = (editor) => {
      editorRef.value = editor // 记录 editor 实例，重要！
    }

    return {
      editorRef,
      valueHtml,
      mode: 'default', // 或 'simple'
      toolbarConfig,
      editorConfig,
      handleCreated
    };
  }
})
</script>

<style scoped lang="less">
.container {
  border: 1px solid #dcdfe6;

}
</style>
